home *** CD-ROM | disk | FTP | other *** search
/ Freelog 125 / Freelog_MarsAvril2015_No125.iso / Internet / gpodder / gpodder-3.8.3-setup.exe / {app} / src / mygpoclient / http.py < prev    next >
Text File  |  2013-02-08  |  5KB  |  145 lines

  1. # -*- coding: utf-8 -*-
  2. # gpodder.net API Client
  3. # Copyright (C) 2009-2013 Thomas Perl and the gPodder Team
  4. #
  5. # This program is free software: you can redistribute it and/or modify
  6. # it under the terms of the GNU General Public License as published by
  7. # the Free Software Foundation, either version 3 of the License, or
  8. # (at your option) any later version.
  9. #
  10. # This program is distributed in the hope that it will be useful,
  11. # but WITHOUT ANY WARRANTY; without even the implied warranty of
  12. # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  13. # GNU General Public License for more details.
  14. #
  15. # You should have received a copy of the GNU General Public License
  16. # along with this program.  If not, see <http://www.gnu.org/licenses/>.
  17.  
  18. import urllib2
  19. import cookielib
  20. import mygpoclient
  21.  
  22. class SimpleHttpPasswordManager(urllib2.HTTPPasswordMgr):
  23.     """Simplified password manager for urllib2
  24.  
  25.     This class always provides the username/password combination that
  26.     is passed to it as constructor argument, independent of the realm
  27.     or authuri that is used.
  28.     """
  29.  
  30.     # The maximum number of authentication retries
  31.     MAX_RETRIES = 3
  32.  
  33.     def __init__(self, username, password):
  34.         self._username = username
  35.         self._password = password
  36.         self._count = 0
  37.  
  38.     def find_user_password(self, realm, authuri):
  39.         self._count += 1
  40.         if self._count > self.MAX_RETRIES:
  41.             return (None, None)
  42.         return (self._username, self._password)
  43.  
  44. class HttpRequest(urllib2.Request):
  45.     """Request object with customizable method
  46.  
  47.     The default behaviour of urllib2.Request is unchanged:
  48.  
  49.     >>> request = HttpRequest('http://example.org/')
  50.     >>> request.get_method()
  51.     'GET'
  52.     >>> request = HttpRequest('http://example.org/', data='X')
  53.     >>> request.get_method()
  54.     'POST'
  55.  
  56.     However, it's possible to customize the method name:
  57.  
  58.     >>> request = HttpRequest('http://example.org/', data='X')
  59.     >>> request.set_method('PUT')
  60.     >>> request.get_method()
  61.     'PUT'
  62.     """
  63.     def set_method(self, method):
  64.         setattr(self, '_method', method)
  65.  
  66.     def get_method(self):
  67.         if hasattr(self, '_method'):
  68.             return getattr(self, '_method')
  69.         else:
  70.             return urllib2.Request.get_method(self)
  71.  
  72.  
  73. # Possible exceptions that will be raised by HttpClient
  74. class Unauthorized(Exception): pass
  75. class NotFound(Exception): pass
  76. class BadRequest(Exception): pass
  77. class UnknownResponse(Exception): pass
  78.  
  79.  
  80. class HttpClient(object):
  81.     """A comfortable HTTP client
  82.  
  83.     This class hides the gory details of the underlying HTTP protocol
  84.     from the rest of the code by providing a simple interface for doing
  85.     requests and handling authentication.
  86.     """
  87.     def __init__(self, username=None, password=None):
  88.         self._username = username
  89.         self._password = password
  90.         self._cookie_jar = cookielib.CookieJar()
  91.         cookie_handler = urllib2.HTTPCookieProcessor(self._cookie_jar)
  92.         if username is not None and password is not None:
  93.             password_manager = SimpleHttpPasswordManager(username, password)
  94.             auth_handler = urllib2.HTTPBasicAuthHandler(password_manager)
  95.             self._opener = urllib2.build_opener(auth_handler, cookie_handler)
  96.         else:
  97.             self._opener = urllib2.build_opener(cookie_handler)
  98.  
  99.     @staticmethod
  100.     def _prepare_request(method, uri, data):
  101.         """Prepares the HttpRequest object"""
  102.  
  103.         request = HttpRequest(uri, data)
  104.         request.set_method(method)
  105.         request.add_header('User-agent', mygpoclient.user_agent)
  106.         return request
  107.  
  108.     @staticmethod
  109.     def _process_response(response):
  110.         return response.read()
  111.  
  112.     def _request(self, method, uri, data, **kwargs):
  113.         """Request and exception handling
  114.  
  115.         Carries out a request with a given method (GET, POST, PUT) on
  116.         a given URI with optional data (data only makes sense for POST
  117.         and PUT requests and should be None for GET requests).
  118.         """
  119.         request = self._prepare_request(method, uri, data)
  120.         try:
  121.             response = self._opener.open(request)
  122.         except urllib2.HTTPError, http_error:
  123.             if http_error.code == 404:
  124.                 raise NotFound()
  125.             elif http_error.code == 401:
  126.                 raise Unauthorized()
  127.             elif http_error.code == 400:
  128.                 raise BadRequest()
  129.             else:
  130.                 raise UnknownResponse(http_error.code)
  131.         return self._process_response(response)
  132.  
  133.     def GET(self, uri):
  134.         """Convenience method for carrying out a GET request"""
  135.         return self._request('GET', uri, None)
  136.  
  137.     def POST(self, uri, data):
  138.         """Convenience method for carrying out a POST request"""
  139.         return self._request('POST', uri, data)
  140.  
  141.     def PUT(self, uri, data):
  142.         """Convenience method for carrying out a PUT request"""
  143.         return self._request('PUT', uri, data)
  144.  
  145.